<?php

/**
 * 易通跨境 SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shopyitong;
use App\Model\PssModel\ServiceConfig;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;
use Hyperf\Utils\WaitGroup;
use function GuzzleHttp\json_encode;

class ShopyitongApiClient
{
    private $account  = 'shopyitong';
    protected $config;
    protected $RouteMap = [
        'createOrder'          => 'deliveryorder.create',
        'cancelOrder'          => 'order.cancel',
        'queryGoodsList'       => 'inventory.query.wms',
    ];
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        ini_set('serialize_precision', 16);
        
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        //运费
        $deliver_money  = $orderInfo['deliver_money'];
        //商品下单组
        $orderItems = [];
        $productAmt     = $TaxAmt = 0 ;
        foreach ($params['orderGoods'] as $key => $item )
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //如果商品除不尽，得多取以为，减去实际金额为折扣，折扣不能为负数
            if( $key == 0 ) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money,(string)$quantity,3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney,(string)100,1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100,2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney,2);
            }
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,3);
            $singleGoodsPrice   = ceil(bcmul((string)$singleGoodsPrice,(string)'100',1));
            $singleGoodsPrice   = bcdiv((string)$singleGoodsPrice,'100',2);
            $totalGoods         = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);

            //含税税率
            $tax_rate           = bcadd('1', (string)$item['tax_rate'],4);
            
            //不含税价格
            $not_tax_price      = bcdiv((string)$singleGoodsPrice, (string)$tax_rate,3);
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = ceil(bcmul((string)$not_tax_price,(string)'100',1));
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price      = bcdiv((string)$not_tax_price,'100',2);
            
            //税金
            $singleGoodsTax     = bcsub((string)$singleGoodsPrice, (string)$not_tax_price,3);
            
            //单个商品总税金
            $totalGoodsTax  = bcmul((string)$singleGoodsTax,(string)$buyAcount,2);
            
            //单个商品总不含税价格
            $totalGoods     = bcmul((string)$not_tax_price,(string)$buyAcount,2);
            //商品组
            $orderItems[] = [
                'itemSort'      => $key+1,
                'itemCode'      => $item['supplier_skucode'],
                'qty'           => $buyAcount,
                'price'         => $not_tax_price,
            ];

            $productAmt = bcadd((string)$productAmt,(string)$totalGoods,2);
            $TaxAmt = bcadd((string)$TaxAmt,(string)$totalGoodsTax,2);
        }
        //实际下单金额
        $real_total_money = $orderInfo['real_total_money'];
        //订单总金额 = 含税商品总金额 + 运费 - 优惠金额
        $ActualPaidAmt = bcadd((string)$productAmt,(string)$TaxAmt,2);
        //优惠金额
        $discount_money = bcsub((string)$ActualPaidAmt,$real_total_money,2);
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        
        //支付时间
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time();
        $pay_time       = date('Y-m-d H:i:s',$pay_time);
        
        
        //支付流水号
        $pay_sn         = $order['paySerial']??$orderInfo['pay_sn'];
        $deduction      = 0.00;
        
//         //获取上游供应商支付方式路由
//         $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
//         $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
//         $pay_value      = ServiceConfig::instance()->getConfigByEventsValue($this->account, ServiceConfig::TYPE_PAY, $PayCompanyCode);
//         if (empty($pay_value)) {
//             return Normal::returnCode(Normal::FAIL, "支付公司编码：【{$PayCompanyCode}】未映射，请联系管理员处理");
//         } 
        //电商平台信息
        $enterpriseNum = $apply_extends['enterpriseNum'] ?? '';
        $enterpriseNum = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;
        //创建订单数据
        $data = [
            'modifyMark'        => "ADD",
            'version'           => "",
            'warehouseCode'     => $this->config["warehouseCode"],
            'billNo'            => "YT2019",
            'ebcOmsCode'        => $enterpriseNum,
            'ebpOmsCode'        => $this->config['ebpOmsCode'],
            'logisticsOmsCode'  => $this->config['logisticsOmsCode'],
            'payOmsCode'        => "",
            'orderNo'           => $orderInfo['supplier_dsn'],
            'payNo'             => $pay_sn,
            'assureCode'        => $this->config['assureCode'],
            'buyerIdType'       => 1,
            'buyerIdNumber'     => $orderInfo['buyer_idcard'],
            'buyerName'         => $orderInfo['buyer_realname'],
            'buyerRegNo'        => $orderInfo['buyer_phone'],
            'buyerTelephone'    => $orderInfo['buyer_phone'],
            'consigneeAddress'  => $orderInfo['province'].$orderInfo['city'].$orderInfo['district'].$orderInfo['receive_address'],
            'consigneePhone'    => $orderInfo['recveive_phone'],
            'consigneeName'     => $orderInfo['receive_name'],
            'province'          => $orderInfo['province'],
            'city'              => $orderInfo['city'],
            'area'              => $orderInfo['district'],
            'freight'           => (float)$deliver_money,
            'discount'          => (float)$discount_money,
            'goodsValue'        => (float)$productAmt,
            'taxTotal'          => (float)$TaxAmt,
            'acturalPaid'       => (float)$real_total_money,
            'grossWeight'       => 0,
            'netWeight'         => 0,
            'senderName'        => "易通跨境",
            'senderAddress'     => "郑州新郑综合保税区",
            'senderPhone'       => "0371-89906322",
            'orderTime'         => date("Y-m-d H:i:s",$orderInfo['cd']),
            'sellerNote'        => $orderInfo['order_remark'],
            'orderItems'        => $orderItems
        ];
        $requestParam = [
            'method'    => 'createOrder',
            'data'      =>$data,
        ];
        return $this->execute($requestParam);
    }
   
    /**
     * 获取取消订单
     */
    public function cancelOrder( $params = [] ) 
    {
        if( empty($params['supplierOrder'])) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder ");
        }
        //组装订单参数
        $orderCode = $params['supplierOrder']["supplier_dsn"];
        $data = [
            'omsCode'   =>$this->config["omsCode"],
            'orderCode' => $orderCode,
            'orderType' => "JYCK",
        ];
        $requestParam = [
            'method'    => 'cancelOrder',
            'data'      =>$data,
        ];
        return $this->execute($requestParam);
    }
    
    
    /**
     * 查询商品信息
     */
    public function queryGoodsListBykeyNo( $params = [] )
    {
        $keyNos=$params["keyNos"];
        $newData=[];
        $count=count($keyNos);
        $wg = new WaitGroup();
        $wg->add($count);
        foreach ($keyNos as $key){
            co(function () use ($wg,$key,&$newData) {
                $data = [
                    'criteriaList'=>[
                        'itemCode'     => $key,
                        'ownerCode'    => $this->config["omsCode"],
                    ]
                ];
                $requestParam = [
                    'method'    => 'queryGoodsList',
                    'data'      => $data,
                ];
                $response = $this->execute($requestParam);
                if ($response['code']==Normal::SUC && isset($response['data']["data"]["items"]) && $response['data']["data"]["items"]){
                    $newData[]=$response['data']["data"]["items"];
                }
                $wg->done();
            });
        }
        $wg->wait();
        $result = ['total' => count($newData),'data' => $newData];
        return Normal::returnCode(Normal::SUC, '获取成功', $result);
    }
    /**
     * 加签
     * @param array $param
     */
      public function getSign(string $method, array $data = []){
        $param = [
            'name'      => $method,
            'version'   => '',
            'format'    => 'json',
            'app_key'   =>  $this->config["appKey"],
            'data'      => rawurlencode(json_encode($data,JSON_UNESCAPED_UNICODE)),
            'timestamp' => date("Y-m-d H:i:s")
        ];
        ksort($param);
        $str = '';
        foreach ($param as $key => $value) {
            $str .= $key. $value;
        }
        
        $secret = $this->config["appSecret"];
        $signstr = $secret.$str.$secret;
        $signstr = strtoupper(md5($signstr));
        $param['sign'] = $signstr;
        return $param;
    }

    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )  
    {
        if(empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        $method = $param['method'];
        $url = $this->config['baseurl'];
        
        $param['data'] = $this->getSign($this->RouteMap[$method],$param["data"]);

        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param['data'],
                'method'    => 'post',
                'format'    => 'json',
                'header'    => [
                    "Content-Type:application/json",
                    "Accept:application/json",
                    "Accept-Encoding:utf-8"
                ],
        
            ],
        ];
        if( in_array($method,['queryGoodsList']) ) {
            $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
//         $res='{
//     "code": "0",
//     "data": {
//         "flag": "success",
//         "items": [
//             {
//                 "batchCode": "H2303040000050",
//                 "expireDate": "2025-09-01",
//                 "inventoryType": "ZP",
//                 "itemCode": "WLMTEST02",
//                 "itemId": "WLMTEST02",
//                 "lockQuantity": 0,
//                 "produceCode": "",
//                 "productDate": "2022-09-02",
//                 "quantity": 141
//             },
//             {
//                 "batchCode": "H2303040000051",
//                 "expireDate": "2025-05-01",
//                 "inventoryType": "ZP",
//                 "itemCode": "WLMTEST02",
//                 "itemId": "WLMTEST02",
//                 "lockQuantity": 0,
//                 "produceCode": "",
//                 "productDate": "2022-05-02",
//                 "quantity": 1609
//             }
//         ],
//         "success": true
//     }
// }';
        $resHttp = @json_decode($res,true);
        if(isset($resHttp['code']) && $resHttp['code'] == 0 ) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        $message = isset($resHttp['msg']) ? $resHttp['msg'] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message);
    }
    
   
}